<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue';

import { Icon } from '@/components/core/icon';

import { ElButton, ElEmpty } from 'element-plus';

import { useCalculate } from '../hooks/useCalculate';
import { useKeyboard } from '../hooks/useKeyboard';
import {
  CLEAR_KEYS,
  DIGITS,
  ERASE_KEYS,
  OPERATORS,
  RESULT_KEYS,
} from '@/lib/shared/constants';
import Grid from './Grid.vue';
import Screen from './Screen.vue';

defineOptions({
  name: 'Calculator',
});
const { nowRect } = defineProps({
  nowRect: {
    default: () => ({}),
    type: Object,
  },
});
const emits = defineEmits(['resize']);
const {
  addDigit,
  addOperator,
  calculateResult,
  clear,
  eraseLast,
  error,
  memory,
} = useCalculate();
const keyboard = useKeyboard();
const history = ref(false);
const records = ref<string[]>([]);
const colWidth = 164;
const onShowHistory = (show: boolean) => {
  history.value = show;
  const width = (show ? 300 : -300) / 2;
  const data = { left: nowRect.left - width, right: nowRect.right - width };
  emits('resize', data);
};
const onClearHistory = () => {
  records.value = [];
};
const onCalculateResult = () => {
  let formula = memory.value;
  calculateResult();
  if (formula && formula !== memory.value) {
    formula += `=${memory.value}`;
    records.value.unshift(formula);
  }
};

onMounted(() => {
  keyboard.addListener((e: KeyboardEvent) => {
    const key = e.key === ',' ? '.' : e.key;

    if (DIGITS.includes(key)) addDigit(key);
    if (OPERATORS.includes(key)) addOperator(key);
    if (RESULT_KEYS.includes(key)) {
      let formula = memory.value;
      calculateResult();
      if (formula && formula !== memory.value) {
        formula += `=${memory.value}`;
        records.value.push(formula);
      }
    }
    if (ERASE_KEYS.includes(key)) eraseLast();
    if (CLEAR_KEYS.includes(key)) clear();
  });
});

onBeforeUnmount(() => {
  keyboard.removeAllListeners();
});
</script>

<template>
  <div class="wos-calculator">
    <div v-if="history" class="history">
      <div class="history-header">
        历史记录
        <Icon
          class="text-gray-500 cursor-pointer hover:text-gray-100"
          icon="mdi:delete-outline"
          @click="onClearHistory"
        />
      </div>
      <ElEmpty v-if="records.length === 0" description="尚无历史记录" />
      <div v-else class="history-record">
        <template v-for="record in records" :key="record">
          <p>{{ record }}</p>
        </template>
      </div>
    </div>
    <Grid :gap="2" class="grid">
      <Screen
        :error="error"
        :text="memory"
        class="h-24 col-span-4"
        @history="onShowHistory"
      />

      <div class="w-full col-span-4 buttons">
        <ElButton
          :style="`width: ${colWidth}px;border-top-left-radius:8px`"
          color="#664f63"
          @click="clear"
        >
          C
        </ElButton>
        <ElButton color="#664f63" @click="eraseLast">
          <Icon icon="mdi:clear-outline" />
        </ElButton>
        <ElButton
          color="#ff9f0a"
          style="border-top-right-radius: 8px"
          @click="addOperator('/')"
        >
          ÷
        </ElButton>

        <ElButton
          v-for="number in ['7', '8', '9']"
          :key="number"
          color="#836378"
          @click="addDigit(number)"
        >
          {{ number }}
        </ElButton>
        <ElButton color="#ff9f0a" @click="addOperator('*')">×</ElButton>

        <ElButton
          v-for="number in ['4', '5', '6']"
          :key="number"
          color="#836378"
          @click="addDigit(number)"
        >
          {{ number }}
        </ElButton>
        <ElButton color="#ff9f0a" @click="addOperator('-')">-</ElButton>

        <ElButton
          v-for="number in ['1', '2', '3']"
          :key="number"
          color="#836378"
          @click="addDigit(number)"
        >
          {{ number }}
        </ElButton>
        <ElButton color="#ff9f0a" @click="addOperator('+')">+</ElButton>

        <ElButton
          :style="`width: ${colWidth}px; border-bottom-left-radius:8px;`"
          color="#836378"
          @click="addDigit('0')"
        >
          0
        </ElButton>
        <ElButton color="#836378" @click="addDigit('.')"> . </ElButton>
        <ElButton
          color="#ff9f0a"
          style="border-bottom-right-radius: 8px"
          @click="onCalculateResult"
        >
          =
        </ElButton>
      </div>
    </Grid>
  </div>
</template>
<style lang="scss">
.wos-calculator {
  display: flex;
  gap: 8px;
  width: 100%;
  height: 100%;
  padding: 8px;

  .el-button + .el-button {
    margin: 0;
  }

  .history {
    flex: 1;
    height: 100%;
    overflow: auto;

    .history-header {
      position: sticky;
      top: 0;
      display: flex;
      justify-content: space-between;
      padding-bottom: 8px;
      background-color: var(--wos-box-center-bg);
    }

    .history-record {
      padding-right: 8px;
      text-align: right;
      user-select: all;
    }
  }

  .grid {
    width: 334px;
    height: 100%;

    .buttons {
      display: flex;
      flex: 1;
      flex-wrap: wrap;
      justify-content: space-around;
    }

    .el-button {
      width: 80px;
      height: 70px;
      padding: 0;
      font-size: 18px;
      color: #fff;
      border-radius: 0;
    }
  }
}
</style>
